home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
prolog
/
modprolg
/
mod-prol.lha
/
Prolog
/
sim
/
load_work.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-01
|
12KB
|
403 lines
/************************************************************************
* *
* The SB-Prolog System *
* Copyright SUNY at Stony Brook, 1986; University of Arizona, 1987 *
* *
************************************************************************/
/*-----------------------------------------------------------------
SB-Prolog is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY. No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing. Refer to the SB-Prolog General Public
License for full details.
Everyone is granted permission to copy, modify and redistribute
SB-Prolog, but only under the conditions described in the
SB-Prolog General Public License. A copy of this license is
supposed to have been given to you along with SB-Prolog so you
can know your rights and responsibilities. It should be in a
file named COPYING. Among other things, the copyright notice
and this notice must be preserved on all copies.
------------------------------------------------------------------ */
/****************************************************************************
* *
* This file has been changed by to include Modules Extensions *
* Changes by : Brian Paxton 1991/92 *
* December 1991 *
* *
* Organisation : University of Edinburgh. *
* For : Departments of Computer Science and Artificial Intelligence *
* Fourth Year Project. *
* *
****************************************************************************/
/* load_work.c */
#define DEBUG_OVERFLOW
/*
#define DEBUG_NAMESTRING
#define DEBUG_LOADWORK
*/
#include "sim.h"
#include "aux.h"
/* #include <stdio,h> */
#define ALIGN(type,ptr) ptr = (type)(((LONG)ptr + 3) & 0xfffffffc)
/************************************************************************
* *
* The hash function uses the arity and character string associated *
* with a predicate, constant, or structure to find the proper bucket *
* (a bucket is a linked list within the pcs table) to insert or locate *
* pcs entries. *
* *
************************************************************************/
int hash(name, length, arity) /* hashing function on name,returning a */
CHAR_PTR name; /* bucket number in the hash table */
WORD length;
BYTE arity;
{
int bucknum;
bucknum = arity + 1;
if (length > 0) { /* first */
bucknum = bucknum + *name;
if (length > 1) { /* last */
bucknum = (bucknum << 2) + *(name + length - 1);
if (length > 2) { /* middle */
bucknum = (bucknum << 2) + *(name + length / 2);
if (length > 3)
bucknum = (bucknum << 2) + *(name+(length / 2) - 1);
}
}
}
return abs(bucknum % BUCKET_CHAIN);
} /* end of hash */
/******************************************************************************/
LONG_PTR search(name, length, arity, hash_ptr)
CHAR_PTR name;
BYTE arity;
WORD length;
LONG_PTR hash_ptr;
{
PSC_REC_PTR psc_ptr;
unsigned short i;
struct booleans {
unsigned eq : 1;
unsigned stop : 1;
} flag;
flag.eq = FALSE;
flag.stop = FALSE;
#ifdef DEBUG_LOADWORK
printf("search: name = %s len = %d arity = %d ", name, length, arity);
printf("hash = %08x\n", hash_ptr);
#endif
while (!ISFREE(hash_ptr) && flag.stop == FALSE) {
hash_ptr = (LONG_PTR)FOLLOW(hash_ptr); /* pointer to pair */
psc_ptr = (PSC_REC_PTR)FOLLOW(hash_ptr); /* pointer to psc record */
#ifdef DEBUG_LOADWORK
printf(" hash_ptr %08x psc_ptr %08x *hash_ptr %08x \n",
hash_ptr, psc_ptr, *hash_ptr);
#endif
if (arity == GET_ARITY(psc_ptr) && length == GET_LENGTH(psc_ptr)) {
flag.eq = TRUE;
for (i = 0; i < length && flag.eq == TRUE; i++)
if (*(name + i) != *(GET_NAME(psc_ptr) + i))
flag.eq = FALSE;
}
if (flag.eq == TRUE)
flag.stop = TRUE;
else hash_ptr++;
}
return hash_ptr;
} /* end of search */
/******************************************************************************/
LONG_PTR insert_temp(name, length, hash_ptr)
CHAR_PTR name;
WORD length;
LONG_PTR hash_ptr;
{
PSC_REC_PTR psc_ptr;
LONG_PTR new_pair, stack_top, heap_top;
register CHAR_PTR threg;
LONG i;
/* check for heap overflow */
stack_top = (breg < ereg) ? breg : ereg - ENV_SIZE(cpreg);
heap_top = hreg + 4 + ((length + 3) >> 2);
if (stack_top < heap_top) {
/* garbage_collection("insert_temp"); */
if (stack_top < heap_top) /* still too full */
quit("Heap overflow\n");
}
new_pair = hreg++;
FOLLOW(hash_ptr) = (LONG)new_pair;
PUSHTRAIL((LONG)hash_ptr); /* trail for backtracking */
MAKE_FREE(LONG, *hreg); /* 2nd of pair free */
FOLLOW(new_pair) = (LONG)++hreg; /* 1st of pair points to psc_rec */
psc_ptr= (PSC_REC_PTR)hreg; /* psc_ptr points to the psc entry */
hreg += 2; /* reserve the space on the heap */
/* NO EP FIELD */
/* make nameptr point to next available space on heap */
GET_ETYPE(psc_ptr) = T_ORDI;
GET_ARITY(psc_ptr) = 0;
GET_LENGTH(psc_ptr) = length;
/* GET_NAME(psc_ptr) = name; */
threg = (CHAR_PTR)hreg;
GET_NAME(psc_ptr) = threg; /* copy name, since might write over it !! */
for (i = 0; i < length; i++)
*threg++ = *name++;
hreg = (LONG_PTR)threg;
ALIGN(LONG_PTR, hreg);
return new_pair;
} /* end of insert_temp */
/******************************************************************************/
LONG_PTR insert_perm(name, length, arity, hash_ptr)
CHAR_PTR name;
BYTE arity;
WORD length;
LONG_PTR hash_ptr;
{
PSC_REC_PTR psc_ptr;
LONG_PTR new_pair;
register LONG i;
ALIGN(CHAR_PTR, curr_fence);
new_pair = (LONG_PTR)curr_fence;
FOLLOW(hash_ptr) = (LONG)new_pair; /* prev link to here */
curr_fence += 4; /* point to 2nd of pair */
MAKE_FREE(LONG_PTR,*(LONG_PTR *)curr_fence); /* set 2nd free */
#ifdef DEBUG_LOADWORK
printf("insert_perm %8x %8x\n", curr_fence, *(LONG_PTR)curr_fence);
#endif
curr_fence += 4; /* where we'll put psc_rec */
FOLLOW(new_pair) = (LONG)curr_fence; /* set 1st to pt to psc_rec */
psc_ptr= (PSC_REC_PTR)curr_fence; /* psc_ptr points there too */
curr_fence += 12; /* 12 bytes for psc_rec */
GET_ETYPE(psc_ptr) = T_ORDI;
GET_ARITY(psc_ptr) = arity;
GET_LENGTH(psc_ptr) = length;
GET_NAME(psc_ptr) = curr_fence;
for (i = 0; i < length; i++)
*curr_fence++ = *name++;
ALIGN(CHAR_PTR, curr_fence);
if (curr_fence >= max_fence) {
#ifdef DEBUG_OVERFLOW
printf("Overflow in \"insert_perm\" curr_fence = %08x max_fence = %08x\n",
curr_fence, max_fence);
#endif
quit("Program area overflow\n");
}
return new_pair;
} /* end of insert_perm */
/******************************************************************************/
LONG_PTR insert(name, length, arity, perm)
CHAR_PTR name;
WORD length;
BYTE arity;
BYTE_PTR perm;
{
int bucket_no;
LONG_PTR temp_ptr, perm_ptr, perm_hashptr, temp_hashptr, ret_ptr;
bucket_no = hash(name, length, arity);
perm_hashptr = (LONG_PTR)&hash_table[bucket_no][PERM];
#ifdef DEBUG_LOADWORK
printf("insert: name = %s len = %d arity = %d ", name, length, arity);
printf("bucket = %d perm = %08x hash = %08x\n",
bucket_no, perm_hashptr, *perm_hashptr);
#endif
perm_ptr = search(name, length, arity, perm_hashptr);
if (!ISFREE(perm_ptr)) { /* found perm psc record */
if (!(*perm))
*perm = PERM; /* set perm flag parameter */
return perm_ptr; /* return permanent */
}
temp_hashptr = (LONG_PTR)&hash_table[bucket_no][TEMP]; /* look for temp */
temp_ptr = search(name, length, arity, temp_hashptr);
if (!ISFREE(temp_ptr)) { /* found temp psc record */
if (!(*perm)) /* temporary wanted */
return temp_ptr; /* return ptr to psc record */
else { /* Perm wanted - convert temp to perm */
/*printf("cvting temp to perm: %c %d %d\n", *name, length, arity);*/
perm_ptr = insert_perm(name, length, arity, perm_ptr);
FOLLOW(temp_ptr) = FOLLOW(perm_ptr);
return perm_ptr;
}
} else { /* Insert constant where indicated */
if (*perm)
return insert_perm(name, length, arity, perm_ptr);
else
return insert_temp(name, length, temp_ptr);
}
} /* end of insert */
/************************************?????????????????????*********/
set_temp_ep(psc_ptr, ep)
PSC_REC_PTR psc_ptr;
{
if (ep >= 0) {
GET_ETYPE(psc_ptr) = T_TEMP_PRED;
GET_EP(psc_ptr) = (LONG_PTR)ep;
}
}
/************************************?????????????????????*********/
set_real_ep(psc_ptr, base)
PSC_REC_PTR psc_ptr;
CHAR_PTR base;
{
if (GET_ETYPE(psc_ptr) == T_TEMP_PRED) {
GET_EP(psc_ptr) = (LONG_PTR)(base + (int)GET_EP(psc_ptr)); /*???*/
GET_ETYPE(psc_ptr) = T_PRED;
}
}
/************************************?????????????????????*********/
/*
set_file_ptr(psc_ptr, file_ptr)
PSC_REC_PTR psc_ptr;
FILE *file_ptr;
{
GET_ETYPE(psc_ptr) = T_FILE;
GET_EP(psc_ptr) = (WORD_PTR)(file_ptr);
}
*/
/************************************?????????????????????*********/
/*
unset_file_ptr(psc_ptr)
PSC_REC_PTR psc_ptr;
{
GET_ETYPE(psc_ptr) = T_ORDI;
GET_EP(psc_ptr) = 0;
}
*/
/************************************?????????????????????*********/
namestring(psc_ptr, s)
PSC_REC_PTR psc_ptr;
CHAR_PTR s;
{
LONG i, len;
CHAR_PTR st;
len = GET_LENGTH(psc_ptr);
st = GET_NAME(psc_ptr);
#ifdef DEBUG_NAMESTRING
printf("namestring: len = %d string = %s\n", len, st);
#endif
for (i = 0; i < len; i++)
*s++ = *st++;
*s = '\0';
}
/************************************?????????????????????*********/
/* Added by Brian Paxton to strip off structure tags from filenames */
namestring2(psc_ptr, s)
PSC_REC_PTR psc_ptr;
CHAR_PTR s;
{
LONG i,j, len;
CHAR_PTR st2, st;
len = GET_LENGTH(psc_ptr);
st = GET_NAME(psc_ptr);
i = 0;
st2 = st;
while(i < len && (*st != '_' || *(st+1) != '_'))
{
*st++;
i++;
}
if (i == len)
{
st = st2;
i = 0;
}
else
st += 2;
for (j = i; j < len; j++)
*s++ = *st++;
*s = '\0';
}
/************************************?????????????????????*********/
LONG alloc_perm(size) /* size should be a multiple of 4 */
LONG size;
{
LONG addr;
PSC_REC_PTR psc_ptr;
ALIGN(CHAR_PTR, curr_fence);
addr = (LONG)curr_fence;
psc_ptr = (PSC_REC_PTR)(curr_fence + 4);
*(LONG_PTR)curr_fence = (LONG)psc_ptr; /* pt to psc record being created */
curr_fence += 12; /* no ep */
GET_ETYPE(psc_ptr) = T_BUFF;
GET_ARITY(psc_ptr) = 0;
GET_LENGTH(psc_ptr) = size;
GET_NAME(psc_ptr) = curr_fence;
curr_fence += size;
ALIGN(CHAR_PTR, curr_fence);
if (curr_fence >= max_fence) {
#ifdef DEBUG_OVERFLOW
printf("Overflow in \"alloc_perm\" curr_fence = %08x max_fence = %08x\n",
curr_fence, max_fence);
#endif
quit("Program area overflow\n");
}
return addr;
} /* end of alloc_perm */